/**
 * 场景系统核心模块
 * 处理场景管理、背景、道具、环境效果等
 */

// 场景基础信息接口
export interface SceneInfo {
  id: string
  name: string
  description: string
  category: string
  tags: string[]
  author: string
  version: string
  createdAt: string
  updatedAt: string
}

// 场景层级枚举
export enum SceneLayer {
  BACKGROUND = 'background',
  MIDGROUND = 'midground',
  FOREGROUND = 'foreground',
  OVERLAY = 'overlay'
}

// 场景资源接口
export interface SceneAsset {
  id: string
  name: string
  type: 'background' | 'prop' | 'decoration' | 'effect'
  layer: SceneLayer
  url: string
  thumbnail: string
  position: { x: number; y: number }
  scale: { x: number; y: number }
  rotation: number
  opacity: number
  zIndex: number
  interactive: boolean
  animated: boolean
  metadata: Record<string, any>
}

// 环境效果接口
export interface EnvironmentEffect {
  id: string
  name: string
  type: 'weather' | 'lighting' | 'particle' | 'atmosphere'
  enabled: boolean
  intensity: number
  parameters: Record<string, any>
  duration?: number
  loop: boolean
}

// 场景照明接口
export interface SceneLighting {
  id: string
  type: 'ambient' | 'directional' | 'point' | 'spot'
  color: string
  intensity: number
  position?: { x: number; y: number; z: number }
  direction?: { x: number; y: number; z: number }
  range?: number
  angle?: number
  shadows: boolean
}

// 完整场景定义接口
export interface Scene extends SceneInfo {
  dimensions: {
    width: number
    height: number
    depth?: number
  }
  assets: SceneAsset[]
  lighting: SceneLighting[]
  effects: EnvironmentEffect[]
  camera: {
    position: { x: number; y: number; z: number }
    target: { x: number; y: number; z: number }
    fov: number
    near: number
    far: number
  }
  physics: {
    gravity: { x: number; y: number }
    friction: number
    airResistance: number
  }
  audio: {
    ambientSound?: string
    volume: number
    loop: boolean
  }
  metadata: {
    indoor: boolean
    timeOfDay: 'morning' | 'noon' | 'afternoon' | 'evening' | 'night'
    weather: 'sunny' | 'cloudy' | 'rainy' | 'snowy' | 'stormy'
    season: 'spring' | 'summer' | 'autumn' | 'winter'
  }
}

// 场景实例接口
export interface SceneInstance {
  id: string
  sceneId: string
  name: string
  active: boolean
  timeOffset: number
  globalScale: number
  globalOpacity: number
  overrides: {
    lighting?: Partial<SceneLighting>[]
    effects?: Partial<EnvironmentEffect>[]
    assets?: Partial<SceneAsset>[]
  }
  state: Record<string, any>
}

// 场景管理器类
export class SceneManager {
  private scenes = new Map<string, Scene>()
  private instances = new Map<string, SceneInstance>()
  private activeScene: string | null = null

  // 注册场景
  registerScene(scene: Scene) {
    this.scenes.set(scene.id, scene)
  }

  // 获取场景
  getScene(sceneId: string): Scene | null {
    return this.scenes.get(sceneId) || null
  }

  // 获取所有场景
  getAllScenes(): Scene[] {
    return Array.from(this.scenes.values())
  }

  // 创建场景实例
  createInstance(sceneId: string, instanceId: string, options: Partial<SceneInstance> = {}): SceneInstance | null {
    const scene = this.getScene(sceneId)
    if (!scene) return null

    const instance: SceneInstance = {
      id: instanceId,
      sceneId,
      name: options.name || scene.name,
      active: options.active ?? true,
      timeOffset: options.timeOffset || 0,
      globalScale: options.globalScale || 1,
      globalOpacity: options.globalOpacity || 1,
      overrides: options.overrides || {},
      state: options.state || {}
    }

    this.instances.set(instanceId, instance)
    return instance
  }

  // 激活场景
  activateScene(instanceId: string): boolean {
    const instance = this.getInstance(instanceId)
    if (!instance) return false

    // 停用当前活动场景
    if (this.activeScene) {
      const currentInstance = this.getInstance(this.activeScene)
      if (currentInstance) {
        currentInstance.active = false
      }
    }

    // 激活新场景
    instance.active = true
    this.activeScene = instanceId
    return true
  }

  // 获取活动场景
  getActiveScene(): SceneInstance | null {
    return this.activeScene ? this.getInstance(this.activeScene) : null
  }

  // 获取场景实例
  getInstance(instanceId: string): SceneInstance | null {
    return this.instances.get(instanceId) || null
  }

  // 更新场景实例
  updateInstance(instanceId: string, updates: Partial<SceneInstance>) {
    const instance = this.instances.get(instanceId)
    if (instance) {
      Object.assign(instance, updates)
    }
  }

  // 删除场景实例
  removeInstance(instanceId: string) {
    if (this.activeScene === instanceId) {
      this.activeScene = null
    }
    this.instances.delete(instanceId)
  }

  // 获取场景的渲染数据
  getSceneRenderData(instanceId: string): any {
    const instance = this.getInstance(instanceId)
    if (!instance) return null

    const scene = this.getScene(instance.sceneId)
    if (!scene) return null

    // 合并场景数据和实例覆盖
    const renderData = {
      scene: { ...scene },
      instance: { ...instance },
      assets: this.mergeAssets(scene.assets, instance.overrides.assets || []),
      lighting: this.mergeLighting(scene.lighting, instance.overrides.lighting || []),
      effects: this.mergeEffects(scene.effects, instance.overrides.effects || [])
    }

    return renderData
  }

  // 合并资源
  private mergeAssets(sceneAssets: SceneAsset[], overrides: Partial<SceneAsset>[]): SceneAsset[] {
    const merged = [...sceneAssets]
    
    overrides.forEach(override => {
      if (override.id) {
        const index = merged.findIndex(asset => asset.id === override.id)
        if (index >= 0) {
          merged[index] = { ...merged[index], ...override }
        }
      }
    })
    
    return merged
  }

  // 合并照明
  private mergeLighting(sceneLighting: SceneLighting[], overrides: Partial<SceneLighting>[]): SceneLighting[] {
    const merged = [...sceneLighting]
    
    overrides.forEach(override => {
      if (override.id) {
        const index = merged.findIndex(light => light.id === override.id)
        if (index >= 0) {
          merged[index] = { ...merged[index], ...override }
        }
      }
    })
    
    return merged
  }

  // 合并效果
  private mergeEffects(sceneEffects: EnvironmentEffect[], overrides: Partial<EnvironmentEffect>[]): EnvironmentEffect[] {
    const merged = [...sceneEffects]
    
    overrides.forEach(override => {
      if (override.id) {
        const index = merged.findIndex(effect => effect.id === override.id)
        if (index >= 0) {
          merged[index] = { ...merged[index], ...override }
        }
      }
    })
    
    return merged
  }

  // 搜索场景
  searchScenes(query: string, filters: {
    category?: string
    tags?: string[]
    indoor?: boolean
    timeOfDay?: string
    weather?: string
  } = {}): Scene[] {
    const scenes = this.getAllScenes()
    
    return scenes.filter(scene => {
      // 文本搜索
      const textMatch = !query || 
        scene.name.toLowerCase().includes(query.toLowerCase()) ||
        scene.description.toLowerCase().includes(query.toLowerCase()) ||
        scene.tags.some(tag => tag.toLowerCase().includes(query.toLowerCase()))
      
      // 分类过滤
      const categoryMatch = !filters.category || scene.category === filters.category
      
      // 标签过滤
      const tagsMatch = !filters.tags || 
        filters.tags.every(tag => scene.tags.includes(tag))
      
      // 室内外过滤
      const indoorMatch = filters.indoor === undefined || scene.metadata.indoor === filters.indoor
      
      // 时间过滤
      const timeMatch = !filters.timeOfDay || scene.metadata.timeOfDay === filters.timeOfDay
      
      // 天气过滤
      const weatherMatch = !filters.weather || scene.metadata.weather === filters.weather
      
      return textMatch && categoryMatch && tagsMatch && indoorMatch && timeMatch && weatherMatch
    })
  }
}

// 场景工具类
export class SceneUtils {
  // 计算场景边界
  static calculateBounds(scene: Scene): { min: { x: number; y: number }, max: { x: number; y: number } } {
    let minX = 0, minY = 0, maxX = scene.dimensions.width, maxY = scene.dimensions.height
    
    scene.assets.forEach(asset => {
      const assetMinX = asset.position.x - (asset.scale.x * 100) / 2
      const assetMaxX = asset.position.x + (asset.scale.x * 100) / 2
      const assetMinY = asset.position.y - (asset.scale.y * 100) / 2
      const assetMaxY = asset.position.y + (asset.scale.y * 100) / 2
      
      minX = Math.min(minX, assetMinX)
      maxX = Math.max(maxX, assetMaxX)
      minY = Math.min(minY, assetMinY)
      maxY = Math.max(maxY, assetMaxY)
    })
    
    return {
      min: { x: minX, y: minY },
      max: { x: maxX, y: maxY }
    }
  }

  // 获取场景中心点
  static getSceneCenter(scene: Scene): { x: number; y: number } {
    const bounds = this.calculateBounds(scene)
    return {
      x: (bounds.min.x + bounds.max.x) / 2,
      y: (bounds.min.y + bounds.max.y) / 2
    }
  }

  // 检查点是否在场景内
  static isPointInScene(scene: Scene, point: { x: number; y: number }): boolean {
    const bounds = this.calculateBounds(scene)
    return point.x >= bounds.min.x && point.x <= bounds.max.x &&
           point.y >= bounds.min.y && point.y <= bounds.max.y
  }

  // 获取场景的层级资源
  static getAssetsByLayer(scene: Scene, layer: SceneLayer): SceneAsset[] {
    return scene.assets.filter(asset => asset.layer === layer)
  }

  // 按z-index排序资源
  static sortAssetsByZIndex(assets: SceneAsset[]): SceneAsset[] {
    return [...assets].sort((a, b) => a.zIndex - b.zIndex)
  }
}

// 环境效果工具类
export class EnvironmentEffectUtils {
  // 创建天气效果
  static createWeatherEffect(type: 'rain' | 'snow' | 'fog', intensity: number = 50): EnvironmentEffect {
    const effects = {
      rain: {
        id: 'weather_rain',
        name: '雨效果',
        type: 'weather' as const,
        enabled: true,
        intensity,
        parameters: {
          dropCount: Math.floor(intensity * 2),
          dropSpeed: 5 + intensity * 0.1,
          windStrength: intensity * 0.02,
          color: '#87CEEB'
        },
        loop: true
      },
      snow: {
        id: 'weather_snow',
        name: '雪效果',
        type: 'weather' as const,
        enabled: true,
        intensity,
        parameters: {
          flakeCount: Math.floor(intensity * 1.5),
          fallSpeed: 2 + intensity * 0.05,
          windStrength: intensity * 0.01,
          color: '#FFFFFF'
        },
        loop: true
      },
      fog: {
        id: 'weather_fog',
        name: '雾效果',
        type: 'atmosphere' as const,
        enabled: true,
        intensity,
        parameters: {
          density: intensity * 0.01,
          color: '#F5F5F5',
          movement: intensity * 0.005
        },
        loop: true
      }
    }
    
    return effects[type]
  }

  // 创建照明效果
  static createLightingEffect(type: 'sunset' | 'moonlight' | 'candlelight', intensity: number = 50): EnvironmentEffect {
    const effects = {
      sunset: {
        id: 'lighting_sunset',
        name: '夕阳效果',
        type: 'lighting' as const,
        enabled: true,
        intensity,
        parameters: {
          color: '#FF6B35',
          warmth: intensity * 0.01,
          softness: 0.8
        },
        loop: false
      },
      moonlight: {
        id: 'lighting_moonlight',
        name: '月光效果',
        type: 'lighting' as const,
        enabled: true,
        intensity,
        parameters: {
          color: '#B0C4DE',
          coolness: intensity * 0.01,
          softness: 0.9
        },
        loop: false
      },
      candlelight: {
        id: 'lighting_candlelight',
        name: '烛光效果',
        type: 'lighting' as const,
        enabled: true,
        intensity,
        parameters: {
          color: '#FFD700',
          flicker: intensity * 0.02,
          warmth: 0.9
        },
        loop: true
      }
    }
    
    return effects[type]
  }
}

// 导出默认场景管理器实例
export const defaultSceneManager = new SceneManager()
